﻿using System.Collections.Generic;
using Wedn.Core.Common;
using Wedn.Core.Entity;
using Wedn.Core.Utility;

namespace Wedn.Core.Service
{
    /// <summary>
    /// 标签管理类
    /// </summary>
    public class TermManager
    {
        protected Wedn.Interface.DAL.ITerm dao;
        /// <summary>
        /// 标签管理类构造函数
        /// </summary>
        /// <exception cref="未找到系统数据库访问组件"></exception>
        public TermManager()
        {
            dao = Wedn.Interface.DAOFactory.CreateTermDAOInstance();
            if (dao == null)
            {
                throw new System.Exception("缺失数据库访问组件!");
            }
        }

        /// <summary>
        /// 向标签表中插入一行新的数据, 返回插入数据的主键ID
        /// </summary>
        /// <param name="term">要插入的标签对象</param>
        /// <returns>返回插入数据的主键ID</returns>
        public int Insert(Term term)
        {
            List<Term> cacheList = GetTermListFromCache();
            int n = ExistsName(term.Name);
            if (n != -1)
            {
                return n;
            }
            else if (ExistsSlug(term.Slug))
            {
                term.Slug += "-2";
                cacheList.Add(term);
                return dao.Insert(term);
            }
            else
            {
                cacheList.Add(term);
                return dao.Insert(term);
            }
        }


        /// <summary>
        /// 向标签表中批量插入多行新的数据, 返回插入数据的主键ID数组
        /// </summary>
        /// <param name="term">要插入的标签对象集合</param>
        /// <returns>返回插入数据的主键ID数组</returns>
        public int[] Insert(List<Term> termList)
        {
            List<int> ids = new List<int>();
            foreach (var insertItem in termList)
            {
                ids.Add(Insert(insertItem));
            }
            return ids.ToArray();
        }

        /// <summary>
        /// 根据标签ID删除对应的标签记录, 返回执行结果是否成功
        /// </summary>
        /// <param name="id">要删除记录的ID</param>
        /// <returns>返回执行结果是否成功</returns>
        public bool Delete(int id)
        {
            List<Term> cacheList = GetTermListFromCache();
            cacheList.RemoveAll((other) =>
            {
                return other.Id == id;
            });
            return dao.Delete(id) > 0;
        }

        /// <summary>
        /// 根据标签ID数组删除对应的标签记录, 返回执行结果是否成功
        /// </summary>
        /// <param name="ids">要删除记录的ID数组</param>
        /// <returns>返回执行结果是否成功</returns>
        public bool Delete(int[] ids)
        {
            List<Term> cacheList = GetTermListFromCache();
            //List<Term> tempList = new List<Term>();
            //foreach (var item in cacheList)
            //{
            //    foreach (var i in ids)
            //    {
            //        if (item.Id == i)
            //        {
            //            tempList.Add(item);
            //        }
            //    }
            //}
            foreach (var id in ids)
            {
                cacheList.RemoveAll((other) =>
                {
                    return other.Id == id;
                });
            }

            return dao.Delete(ids) > 0;
        }

        /// <summary>
        /// 更新一个完整的标签对象, 返回执行结果是否成功
        /// </summary>
        /// <param name="term">要更新的对象</param>
        /// <returns>返回执行结果是否成功</returns>
        public bool UpdateTerm(Term term)
        {
            List<Term> cacheList = GetTermListFromCache();
            for (int i = 0; i < cacheList.Count; i++)
            {
                if (term.Id == cacheList[i].Id)
                {
                    cacheList[i].Name = term.Name;
                    cacheList[i].Slug = term.Slug;
                    cacheList[i].Type = term.Type;
                    cacheList[i].ParentId = term.ParentId;
                    cacheList[i].Description = term.Description;
                }
            }

            return dao.UpdateTerm(term) > 0;
        }

        /// <summary>
        /// 更新一个标签常用信息, 返回执行结果是否成功
        /// </summary>
        /// <param name="id">标签ID</param>
        /// <param name="name">更新的名称(不更新则传入null)</param>
        /// <param name="slug">更新的别名(不更新则传入null)</param>
        /// <param name="parentId">更新的父ID(不更新则传入-1)</param>
        /// <param name="description">更新的描述(不更新则传入null)</param>
        /// <returns>返回执行结果是否成功</returns>
        public bool UpdateInfo(int id, string name, string slug, int parentId, string description)
        {
            List<Term> cacheList = GetTermListFromCache();
            for (int i = 0; i < cacheList.Count; i++)
            {
                if (id == cacheList[i].Id)
                {
                    cacheList[i].Name = name;
                    cacheList[i].Slug = slug;
                    cacheList[i].ParentId = parentId;
                    cacheList[i].Description = description;
                }
            }

            return dao.UpdateInfo(id, name, slug, parentId, description) > 0;
        }

        /// <summary>
        /// 批量更新标签父ID, 返回执行结果是否成功
        /// </summary>
        /// <param name="ids">标签ID数组</param>
        /// <param name="parentId">更新的父ID</param>
        /// <returns>返回执行结果是否成功</returns>
        public bool UpdateParentId(int[] ids, int parentId)
        {
            List<Term> cacheList = GetTermListFromCache();
            for (int i = 0; i < cacheList.Count; i++)
            {
                for (int j = 0; j < ids.Length; j++)
                {
                    if (ids[j] == cacheList[i].Id)
                    {
                        cacheList[i].ParentId = parentId;
                    }
                }
            }

            return dao.UpdateParentId(ids, parentId) > 0;
        }

        /// <summary>
        /// 根据标签ID更新标签下项目数, 返回执行结果是否成功
        /// </summary>
        /// <param name="id">要更新的标签ID</param>
        /// <param name="addCount">增加的数量(一般为1)</param>
        /// <returns>返回执行结果是否成功</returns>
        public bool UpdateCount(int id, int addCount)
        {
            List<Term> cacheList = GetTermListFromCache();
            for (int i = 0; i < cacheList.Count; i++)
            {
                if (id == cacheList[i].Id)
                {
                    cacheList[i].Count += addCount;
                }
            }
            return dao.UpdateCount(id, addCount) > 0;
        }

        /// <summary>
        /// 根据标签ID重新统计标签下项目数, 返回执行结果受影响行数
        /// </summary>
        /// <param name="id">要更新的标签ID</param>
        /// <returns>执行结果受影响行数</returns>
        public bool UpdateCount(int id)
        {
            bool res = dao.UpdateCount(id) > 0;
            CacheHelper.SetCache("TermList", GetTermListFromDB());
            return res;
        }

        /// <summary>
        /// 根据标签ID重新统计标签下项目数, 返回执行结果受影响行数
        /// </summary>
        /// <param name="id">要更新的标签ID</param>
        /// <returns>执行结果受影响行数</returns>
        public bool UpdateCount()
        {
            bool res = dao.UpdateCount() > 0;
            CacheHelper.SetCache("TermList", GetTermListFromDB());
            return res;
        }

        /// <summary>
        /// 获取表中主键最大值, 返回主键最大值
        /// </summary>
        /// <returns>主键最大值</returns>
        public int GetMaxId()
        {
            List<Term> cacheList = GetTermListFromCache();
            int max = cacheList[0].Id;
            foreach (var item in cacheList)
            {
                if (item.Id > max)
                {
                    max = item.Id;
                }
            }
            return max;
            //return dao.SelectMaxId();
        }

        /// <summary>
        /// 检查表中是否已经存在该别名, 返回一个布尔值, 存在则为True; 不存在则为False
        /// </summary>
        /// <param name="slug">要确定的别名</param>
        /// <returns>存在返回True; 不存在返回False</returns>
        public bool ExistsSlug(string slug)
        {
            List<Term> cacheList = GetTermListFromCache().FindAll((other) =>
            {
                return other.Slug == slug;
            });
            return cacheList.Count > 0;
            //return dao.Exists(slug);
        }

        /// <summary>
        /// 检查表中是否已经存在该标签名, 返回一个布尔值, 存在则为True; 不存在则为False
        /// </summary>
        /// <param name="name">要确定的标签名</param>
        /// <returns>存在返回该Term的ID; 不存在返回-1</returns>
        public int ExistsName(string name)
        {
            List<Term> cacheList = GetTermListFromCache().FindAll((other) =>
            {
                return other.Name == name;
            });
            if (cacheList.Count > 0)
            {
                return cacheList[0].Id;
            }
            return -1;
            //return dao.Exists(slug);
        }

        /// <summary>
        /// 选取标签总数
        /// </summary>
        /// <param name="where">选择条件(忽略则传入null或空值)(不能使用参数, 要使用参数化写重载)</param>
        /// <returns>总数</returns>
        public int GetTermsCount(string where)
        {
            return dao.SelectTermsCount(where);
        }

        /// <summary>
        /// 根据类型选取标签总数
        /// </summary>
        /// <returns>总数</returns>
        public int GetTermsCountByType(TermType termType)
        {
            List<Term> cacheList = GetTermListFromCache().FindAll((other) =>
            {
                return other.Type == (int)termType;
            });
            //if (cacheList.Count > 0)
            return cacheList.Count;

            //return dao.SelectTermsCountByType((int)termType);
        }

        /// <summary>
        /// 取出当前标签表中的所有标签对象集合, 返回标签对象集合, 如果不存在则返回空集合
        /// </summary>
        /// <returns>标签对象集合</returns>
        public List<Term> GetTermList()
        {
            List<Term> cacheList = GetTermListFromCache();
            //if (cacheList.Count > 0)
            return cacheList;

            //List<Term> list = dao.SelectTermList();
            //if (list == null)
            //    list = new List<Term>();
            //return list;
        }

        /// <summary>
        /// 根据类型选取标签对象集合, 如果不存在则返回空集合
        /// </summary>
        /// <param name="termType">标签类型</param>
        /// <returns>标签对象</returns>
        public List<Term> GetTermList(TermType termType)
        {
            //首先从缓存中取, 
            List<Term> cacheList = GetTermListFromCache().FindAll((other) =>
            {
                return other.Type == (int)termType;
            });
            return cacheList;
        }

        /// <summary>
        /// 根据类型和父ID选取标签对象集合, 如果不存在则返回空集合
        /// </summary>
        /// <param name="termType">标签类型</param>
        /// <param name="parentId">父ID</param>
        /// <returns>标签对象集合</returns>
        public List<Term> GetTermList(TermType termType, int parentId)
        {
            //首先从缓存中取, 
            List<Term> cacheList = GetTermListFromCache().FindAll((other) =>
            {
                return other.Type == (int)termType && other.ParentId == parentId;
            });
            //if (cacheList.Count > 0)
            return cacheList;

            //List<Term> list = dao.SelectTermList((int)termType, parentId);
            //if (list == null)
            //    list = new List<Term>();
            //return list;
        }

        /// <summary>
        /// 根据对象ID和类型选取标签对象集合, 如果不存在则返回空集合
        /// </summary>
        /// <param name="objectId">对象ID</param>
        /// <param name="objectType">对象类型(0:Post, 1:User, 2:Link, 3:Comment)</param>
        /// <returns>标签对象集合</returns>
        public List<Term> GetTermList(int objectId, ObjectType objectType)
        {
            ////首先从缓存中取, 
            //List<Term> cacheList = GetTermListFromCache().FindAll((other)=>{
            //return other.o
            //});

            List<Term> list = dao.SelectTermListByObject(objectId, (int)objectType);
            if (list == null)
                list = new List<Term>();

            return list;
        }

        /// <summary>
        /// 根据ID选取标签对象, 不存在则返回null
        /// </summary>
        /// <param name="termid">标签ID</param>
        /// <returns>标签对象</returns>
        public Term GetTerm(int termid)
        {
            //首先从缓存中取, 
            List<Term> cacheList = GetTermListFromCache();
            foreach (var item in cacheList)
            {
                if (item.Id == termid)
                    return item;
            }
            return dao.SelectTerm(termid);
        }

        /// <summary>
        /// 根据ID和类型选取标签对象, 不存在则返回null
        /// </summary>
        /// <param name="slug">标签别名</param>
        /// <returns>标签对象</returns>
        public Term GetTerm(string slug)
        {
            //首先从缓存中取, 
            List<Term> cacheList = GetTermListFromCache();
            foreach (var item in cacheList)
            {
                if (item.Slug == slug)
                    return item;
            }
            return dao.SelectTerm(slug);
        }

        /// <summary>
        /// 尝试从缓存中取数据, 如果缓存中为null 则从数据库中取数据, 
        /// 返回对象集合, 不存在则返回空集合;
        /// </summary>
        /// <returns>返回对象集合, 不存在则返回null;</returns>
        public List<Term> GetTermListFromCache()
        {
            List<Term> cacheList = CacheHelper.GetCache("TermList") as List<Term>;
            if (cacheList == null)
            {
                cacheList = GetTermListFromDB();
                if (cacheList == null)
                {
                    //数据库中也没有数据
                    return new List<Term>();
                }
                else
                {
                    //数据库中有数据, 缓存起来
                    CacheHelper.SetCache("TermList", cacheList);
                }
            }
            return cacheList;
        }

        /// <summary>
        /// 从数据库中取数据, 
        /// 返回对象集合, 不存在则返回null;
        /// </summary>
        /// <returns>返回对象集合, 不存在则返回null;</returns>
        public List<Term> GetTermListFromDB()
        {
            return dao.SelectTermList();
        }
    }
}
